import argparse
from pathlib import Path

from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import StaleElementReferenceException

from browser import Browser


class ListCities(Browser):

    """ Этот класс предоставляет работу со списокм городов """

    def __init__(self):

        data = self.get_input_parameters()
        self.start_parsing(data)


    def get_input_parameters(self):

        """ Получаем входные аргументы """

        parser = argparse.ArgumentParser()

        parser.add_argument('-u', dest='update')
        parser.add_argument('-a', dest='add')

        arguments = parser.parse_args()

        well_what_update = arguments.update
        well_what_add = arguments.add

        if (well_what_update is None) and (well_what_add is None):

            print('Никакого дейcтсвия не было выбрано')
            return 'Закончить'


        if not (well_what_update is None) and not (well_what_add is None):

            print('Должно быть выбрано только одно действие')
            return 'Закончить'

        data = (well_what_update, well_what_add)

        return data


    def get_cities_to_add(self):

        """ Получаем города для добалвения """

        content = []
        data_folder = Path('cities/')
        file_to_open = data_folder/'cities_to_add.txt'

        with open(file_to_open) as file:

            for line in file:

                city = line.strip()
                content.append(city)

        return content


    def open_list_cities(self, browser):

        """ Открываем список городов """

        open_cities_button = browser.find_elements(
            By.XPATH,
            '//header//img/../..//button'
        )

        if open_cities_button: open_cities_button[0].click()


    def get_list_links_to_cities(self, browser):

        """ Получаем список ссылок на города """

        while True:

            list_links_to_cities_selenium = browser.find_elements(
                By.XPATH,
                '//label/following::div[1]/a'
            )

            if list_links_to_cities_selenium: break
            print('Ждем список гордов')

        try:

            list_links_to_cities_done = [link.get_attribute('href') for link in list_links_to_cities_selenium]

        except StaleElementReferenceException as error:

            pass


        return list_links_to_cities_selenium


    def add_link_to_city(self, link):

        """ Добавляем ссылку на город """

        def check_there_a_link(link):

            """ Проверяем есть ли эта ссылка в файле """

            content = []
            data_folder = Path('cities/')
            file_to_open = data_folder/'list_of_cities.txt'

            with open(file_to_open) as file:

                for line in file:

                    content.append(line)

            if link in ' '.join(content): return 'Такая ссылка уже есть'


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        well_what = check_there_a_link(link)
        if well_what == 'Такая ссылка уже есть':

            print(f'Такая ссылка уже есть ({link})')
            return

        data_folder = Path('cities/')
        file_to_open = data_folder/'list_of_cities.txt'

        with open(file_to_open, 'a') as file:

            file.write(f'{link}\n')
            print(f'Записали - {link}')


    def update_list_cities(self):

        """ Обновляем список городов """

        def get_link(browser, link_number, list_links):

            """ Получаем ссылку с города """

            try:

                link = list_links[link_number]

            except IndexError:

                print('Города закончились')
                return 'Города закончились'

            action = ActionChains(browser)
            action.move_to_element(link)
            action.perform()    # Перемещаемся к элементу

            link.click()        # Переходим на другую страницу

            current_url = browser.current_url

            return current_url



        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИИ

        link_number = 0

        while True:

            browser = self.get_browser(display_browser='yes')
            browser.get('https://profi.ru/')

            self.open_list_cities(browser)
            list_links_to_cities = self.get_list_links_to_cities(browser)
            link = get_link(browser, link_number, list_links_to_cities)

            if link == 'Города закончились': break

            self.add_link_to_city(link)

            browser.quit()
            link_number += 1

        return


    def add_cities_to_list(self):

        """ Добавляем города в список """

        def get_link_to_city(browser, city):

            """ Получаем ссылку на город """

            def entering_city(browser, city):

                """ Вводим город """

                field_for_entering_city = browser.find_element(
                    By.XPATH,
                    '//input[@placeholder="Введите регион или город"]'
                )

                field_for_entering_city.click()
                field_for_entering_city.clear()
                field_for_entering_city.send_keys(city)


            def get_link(browser):

                """ Получаем ссылку """

                while True:

                    try:

                        list_links_to_cities = self.get_list_links_to_cities(browser)
                        list_links_to_cities[0].click()
                        current_link = browser.current_url

                        return current_link

                    except StaleElementReferenceException as error:

                        list_links_to_cities = self.get_list_links_to_cities(browser)


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            entering_city(browser, city)
            link = get_link(browser)

            return link


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        cities_to_add = self.get_cities_to_add()

        for city in cities_to_add:

            browser = self.get_browser(display_browser='yes')
            browser.get('https://profi.ru/?gpId=')

            self.open_list_cities(browser)            # Открываем список городов
            self.get_list_links_to_cities(browser)    # Ждем когда все загрузится
            link = get_link_to_city(browser, city)
            self.add_link_to_city(link)

            browser.quit()


    def start_parsing(self, data):

        """ Начинаем парсинг """

        if data == 'Закончить': return

        update, add = data

        if update:

            self.update_list_cities()
            print('Все')

        if add:

            self.add_cities_to_list()
            print('Ссылки на города были добавлены')


# ТОЧКА ВХОДА

if __name__ == '__main__':

    a = ListCities()
